package com.gateio.flutter.lib_furnace.container

import android.content.Context
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import androidx.activity.OnBackPressedCallback
import androidx.fragment.app.Fragment
import com.gateio.flutter.lib_furnace.GTFlutter
import com.gateio.flutter.lib_furnace.databinding.FlutterFragmentViewBinding
import io.flutter.embedding.android.FlutterFragment
import io.flutter.embedding.android.FlutterSurfaceView
import io.flutter.embedding.android.FlutterTextureView
import io.flutter.embedding.android.FlutterView
import io.flutter.embedding.android.RenderMode
import io.flutter.embedding.android.TransparencyMode
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.embedding.engine.FlutterEngineCache
import io.flutter.plugin.common.BasicMessageChannel
import io.flutter.plugin.common.StringCodec
import io.flutter.plugin.platform.PlatformPlugin
import org.json.JSONException
import org.json.JSONObject

/**
 * Author: Shper
 * Created: 2023/7/12
 */
@Deprecated("已废弃，不再使用")
open class GTFlutterViewFragment : Fragment(), PlatformPlugin.PlatformPluginDelegate {
    companion object {

        const val ARG_ROUTER_NAME = "arg_router_name"
        const val ARG_CACHED_ENGINE_ID = "arg_cached_engine_id"
        const val ARG_IS_TEXTURE_RENDER_MODE = "arg_is_texture_render_mode"
        const val ARG_IS_OPAQUE = "arg_is_opaque"
        const val ARG_SHOULD_AUTOMATICALLY_HANDLE_ON_BACK_PRESSED = "arg_should_automatically_handle_on_back_pressed"

        fun withCachedEngineId(routerName: String,
                               cachedEngineId: String,
                               renderMode: RenderMode = RenderMode.texture,
                               transparencyMode: TransparencyMode = TransparencyMode.opaque,
                               automaticallyHandleOnBackPressed: Boolean = false): GTFlutterViewFragment {
            val frag = GTFlutterViewFragment()
            val args = Bundle()
            args.putString(ARG_ROUTER_NAME, routerName)
            args.putString(ARG_CACHED_ENGINE_ID, cachedEngineId)
            args.putBoolean(ARG_IS_TEXTURE_RENDER_MODE, renderMode == RenderMode.texture)
            args.putBoolean(ARG_IS_OPAQUE, transparencyMode == TransparencyMode.opaque)
            args.putBoolean(ARG_SHOULD_AUTOMATICALLY_HANDLE_ON_BACK_PRESSED, automaticallyHandleOnBackPressed)
            frag.arguments = args
            return frag
        }
    }

    private var mViewBinding: FlutterFragmentViewBinding? = null
    private var flutterViewEngine: GTFlutterViewEngine? = null
    private var flutterView: FlutterView? = null
    private var engineId: String? = null
    internal var configureFlutterEngineFun: FragmentConfigureFlutterEngine? = null

    private var roomCount: Int? = null
    private var originHeight = 0
    private var routerName: String = ""

    // 待删除
    private val nativeScroll: Boolean
        get() = engineId == "/information/chatHomePage:HomeChatroomV2"

    override fun onAttach(context: Context) {
        super.onAttach(context)
        Log.d("GTFlutter", "GTFlutterViewFragment - onAttach")

        // 获取引擎
        if (flutterViewEngine == null) {
            routerName = arguments?.getString(ARG_ROUTER_NAME, "") ?: ""

            arguments?.getString(ARG_CACHED_ENGINE_ID)?.let { cachedEngineId ->
                this@GTFlutterViewFragment.engineId = cachedEngineId
                FlutterEngineCache.getInstance().get(cachedEngineId)?.let { flutterEngine ->
                    setEngineMessageHandler(flutterEngine)
                    flutterViewEngine = GTFlutterViewEngine(flutterEngine)
                }
            }
        }

        // 时候自动处理 onBackPressed
        if (arguments?.getBoolean(ARG_SHOULD_AUTOMATICALLY_HANDLE_ON_BACK_PRESSED, false) == true) {
            requireActivity().onBackPressedDispatcher.addCallback(this, onBackPressedCallback)
        }
//        context.registerComponentCallbacks(this)
    }

    private fun setEngineMessageHandler(flutterEngine: FlutterEngine) {
        if (!nativeScroll) return
        val basicMessageChannel = BasicMessageChannel(
            flutterEngine.dartExecutor,
            "com.gateio.flutter.information.homepage",
            StringCodec.INSTANCE
        )

        basicMessageChannel.setMessageHandler { message, reply ->
            try {
                val jsonObject = JSONObject(message)
                val newCount = jsonObject.getInt("roomCount")
                if (roomCount == newCount) return@setMessageHandler
                roomCount = newCount
                refreshFlutterView()
            } catch (e: JSONException) {
                e.printStackTrace()
            }

        }
    }

    private fun refreshFlutterView() {
        if (flutterView == null || roomCount == null) return
        if (originHeight == 0) {
            originHeight = flutterView!!.measuredHeight
        }
        if (originHeight == 0) return
        if (roomCount == 0) {
            resetParam()
        } else {
            val reMeasureHeight = dp2px((roomCount!! * 64 + 47 + 66).toFloat())
            if (reMeasureHeight <= originHeight) {
                resetParam()
            } else {
                mViewBinding?.root?.layoutParams = mViewBinding?.root?.layoutParams?.also {
                    it.height = FrameLayout.LayoutParams.WRAP_CONTENT
                }
                flutterView?.layoutParams = flutterView?.layoutParams?.also {
                    it.height = reMeasureHeight
                }
            }
        }
    }

    private fun resetParam() {
        mViewBinding?.root?.layoutParams = mViewBinding?.root?.layoutParams?.also {
            it.height = FrameLayout.LayoutParams.MATCH_PARENT
        }
        flutterView?.layoutParams = flutterView?.layoutParams?.also {
            it.height = FrameLayout.LayoutParams.MATCH_PARENT
        }
    }


    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        Log.d("GTFlutter", "GTFlutterViewFragment - onCreateView")
        if (mViewBinding == null) {
            mViewBinding = FlutterFragmentViewBinding.inflate(inflater)
        }
        return mViewBinding?.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        Log.d("GTFlutter", "GTFlutterViewFragment - onViewCreated")

        // 获取引擎 并且 attachToActivity
        activity?.let { activity ->
            if (flutterView == null) {
                // 默认不透明
                val isOpaque = arguments?.getBoolean(ARG_IS_OPAQUE) == true

                flutterView = if (arguments?.getBoolean(ARG_IS_TEXTURE_RENDER_MODE) == true) {
                    val flutterTextureView = FlutterTextureView(activity)
                    flutterTextureView.isOpaque = isOpaque
                    FlutterView(activity, flutterTextureView)
                } else {
                    val flutterSurfaceView = FlutterSurfaceView(activity, !isOpaque)
                    FlutterView(activity, flutterSurfaceView)
                }

                flutterViewEngine?.attachFlutterView(activity, flutterView!!, this) { flutterEngine ->
                    configureFlutterEngineFun?.invoke(flutterEngine)
                }
                mViewBinding?.root?.layoutParams = mViewBinding?.root?.layoutParams?.also {
                    it.height =
                        if (!nativeScroll) FrameLayout.LayoutParams.MATCH_PARENT else FrameLayout.LayoutParams.WRAP_CONTENT
                } ?: FrameLayout.LayoutParams(
                    FrameLayout.LayoutParams.MATCH_PARENT,
                    if (!nativeScroll) FrameLayout.LayoutParams.MATCH_PARENT else FrameLayout.LayoutParams.WRAP_CONTENT
                )
                mViewBinding?.root?.addView(
                    flutterView, FrameLayout.LayoutParams(
                        FrameLayout.LayoutParams.MATCH_PARENT,
                        if (!nativeScroll) FrameLayout.LayoutParams.MATCH_PARENT else 3000
                    )
                )
                refreshFlutterView()
            }
        }
    }

    override fun onDestroyView() {
        super.onDestroyView()
        Log.d("GTFlutter", "GTFlutterViewFragment - onDestroyView")
    }

    override fun onDestroy() {
        super.onDestroy()
        Log.d("GTFlutter", "GTFlutterViewFragment - onDestroy")

        GTFlutter.pageStartedList.remove(routerName)
    }

    override fun onDetach() {
        super.onDetach()
        Log.d("GTFlutter", "GTFlutterViewFragment - onDetach")

        flutterViewEngine?.detachFlutterView()
        flutterViewEngine = null
        flutterView = null
    }

    // 处理 BackPressedCallback
    private val onBackPressedCallback: OnBackPressedCallback = object : OnBackPressedCallback(true) {
        override fun handleOnBackPressed() {
            onBackPressed()
        }
    }

    // 处理 BackPressed
    open fun onBackPressed() {
        flutterViewEngine?.engine?.navigationChannel?.popRoute()
    }

    // 处理 Flutter 层的 popSystemNavigator 事件
    override fun popSystemNavigator(): Boolean {
        if (arguments?.getBoolean(ARG_SHOULD_AUTOMATICALLY_HANDLE_ON_BACK_PRESSED, false) == true) {
            activity?.let {
                onBackPressedCallback.isEnabled = false
                it.onBackPressedDispatcher.onBackPressed()
                onBackPressedCallback.isEnabled = true
                return true
            }
        }
        return false
    }

    open fun dp2px(dpValue: Float): Int {
        val scale = this.resources.displayMetrics.density
        return (dpValue * scale + 0.5f).toInt()
    }

}